package com.xindaoapp.henghua.db;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;

import com.xindaoapp.henghua.db.DaoMaster.DevOpenHelper;
import com.xindaoapp.henghua.db.model.PropertyDao;
import com.xindaoapp.henghua.db.model.PropertyWithLabelDao;
import com.xindaoapp.henghua.db.model.ScanDatasDao;
import com.xindaoapp.henghua.db.model.SupervisionDao;
import com.xindaoapp.henghua.db.model.TagsDao;
import com.xindaoapp.henghua.db.model.TransportDatasDao;
import com.xindaoapp.henghua.entry.PropertyGatherInfo;
import com.xindaoapp.henghua.entry.PropertyGatherInfo.MODIFIEDTYPE;
import com.xindaoapp.henghua.entry.PropertyLabelInfo;
import com.xindaoapp.henghua.entry.ScanData;
import com.xindaoapp.henghua.entry.SuperVisionInfo;
import com.xindaoapp.henghua.entry.TagsInfo;
import com.xindaoapp.henghua.entry.TransportDataInfo;
import com.xindaoapp.henghua.entry.UnSubmitLabelInfo;

public class XinDaoDBHelper implements IDBHelper {
	private final SQLiteDatabase mSqLiteDatabase;
	private final DaoSession mDaoSession;

	private final PropertyDao mPropertyDao;
	private final PropertyWithLabelDao mPropertyWithLabelDao;
	private final ScanDatasDao mScanDatasDao;
	private final SupervisionDao mSupervisionDao;
	private final TransportDatasDao mTransportDatasDao;
	private final TagsDao mTagsDao;

	public XinDaoDBHelper(Context context) {
		DevOpenHelper helper = new DaoMaster.DevOpenHelper(context, "henghua-db", null);
		mSqLiteDatabase = helper.getWritableDatabase();
		DaoMaster daoMaster = new DaoMaster(mSqLiteDatabase);
		mDaoSession = daoMaster.newSession();
		mPropertyDao = mDaoSession.getPropertyDao();
		mPropertyWithLabelDao = mDaoSession.getPropertyWithLabelDao();
		mScanDatasDao = mDaoSession.getScanDatasDao();
		mSupervisionDao = mDaoSession.getSuperVisionDao();
		mTransportDatasDao = mDaoSession.getTransportDataDao();
		mTagsDao = mDaoSession.getTagsDao();
		
	}

	@Override
	public void insertPropertyGatherInfo(PropertyGatherInfo info) {
		// 将之前的服务器获取的数据进行清空，但是要过滤掉未提交的
		mPropertyDao.insert(info);
		if (null != info.propertyLabelInfos) {
			for (PropertyLabelInfo propertyLabelInfo : info.propertyLabelInfos) {
				propertyLabelInfo.assert_id = info.id;
				mPropertyWithLabelDao.insert(propertyLabelInfo);
			}
		}
		if (null != info.scanDatas) {
			for (ScanData data : info.scanDatas) {
				data.assert_id = info.id;
				mScanDatasDao.insert(data);
			}
		}
		if (null != info.superVisionInfo) {
			mSupervisionDao.insert(info.superVisionInfo);
		}

		if (null != info.transportDataInfo) {
			mTransportDatasDao.insert(info.transportDataInfo);
		}

	}

	@Override
	public List<PropertyGatherInfo> getPropertyGatherInfos() {
		List<PropertyGatherInfo> propertyGatherInfos = mPropertyDao.loadAll();
		Map<String, PropertyGatherInfo> map = new HashMap<String, PropertyGatherInfo>();
		for (PropertyGatherInfo propertyGatherInfo : propertyGatherInfos) {
			map.put(propertyGatherInfo.id, propertyGatherInfo);
		}

		loadPropertyWithLabelDatas(map);
		loadScanDatas(map);
		loadSupervisionDatas(map);
		loadTransportDatas(map);
		return propertyGatherInfos;
	}

	private void loadSupervisionDatas(Map<String, PropertyGatherInfo> map) {
		List<SuperVisionInfo> list = mSupervisionDao.loadAll();
		for (SuperVisionInfo superVisionInfo : list) {
			if (map.containsKey(superVisionInfo.assert_id)) {
				map.get(superVisionInfo.assert_id).superVisionInfo = superVisionInfo;
			}
		}
	}

	private void loadTransportDatas(Map<String, PropertyGatherInfo> map) {
		List<TransportDataInfo> list = mTransportDatasDao.loadAll();
		for (TransportDataInfo info : list) {
			if (map.containsKey(info.assert_id)) {
				map.get(info.assert_id).transportDataInfo = info;
			}
		}
	}

	private void loadPropertyWithLabelDatas(Map<String, PropertyGatherInfo> map) {
		// 初始化其他信息
		List<PropertyLabelInfo> propertyWithLabelDataInfos = mPropertyWithLabelDao.loadAll();
		Map<String, List<PropertyLabelInfo>> propertyLabelInfoMaps = new HashMap<String, List<PropertyLabelInfo>>();
		for (PropertyLabelInfo propertyLabelInfo : propertyWithLabelDataInfos) {
			if (!propertyLabelInfoMaps.containsKey(propertyLabelInfo.assert_id)) {
				List<PropertyLabelInfo> list = new ArrayList<PropertyLabelInfo>();
				list.add(propertyLabelInfo);
				propertyLabelInfoMaps.put(propertyLabelInfo.assert_id, list);
			} else {
				propertyLabelInfoMaps.get(propertyLabelInfo.assert_id).add(propertyLabelInfo);
			}
		}
		Iterator<String> iterator = propertyLabelInfoMaps.keySet().iterator();
		while (iterator.hasNext()) {
			String key = iterator.next();
			if (map.containsKey(key)) {
				map.get(key).propertyLabelInfos = propertyLabelInfoMaps.get(key);
			}
		}
	}

	private void loadScanDatas(Map<String, PropertyGatherInfo> propertyGatherMap) {
		List<ScanData> scandataInfos = mScanDatasDao.loadAll();
		Map<String, List<ScanData>> map = new HashMap<String, List<ScanData>>();
		for (ScanData scanData : scandataInfos) {
			if (map.containsKey(scanData.assert_id)) {
				map.get(scanData.assert_id).add(scanData);
			} else {
				List<ScanData> list = new ArrayList<ScanData>();
				list.add(scanData);
				map.put(scanData.assert_id, list);
			}
		}
		Iterator<String> iterator = map.keySet().iterator();
		while (iterator.hasNext()) {
			String key = iterator.next();
			if (propertyGatherMap.containsKey(key)) {
				propertyGatherMap.get(key).scanDatas = map.get(key);
			}
		}
	}

	@Override
	public void insertUnSubmitLabel(PropertyLabelInfo propertyLabelInfo, ScanData scanData) {
		mPropertyWithLabelDao.insert(propertyLabelInfo);
		mScanDatasDao.insert(scanData);
	}

	@Override
	public List<UnSubmitLabelInfo> getUnSubmitLabels() {
		List<UnSubmitLabelInfo> list = new ArrayList<UnSubmitLabelInfo>();
		Map<String, UnSubmitLabelInfo> map = new HashMap<String, UnSubmitLabelInfo>();
		List<PropertyLabelInfo> propertyLabelInfos = mPropertyWithLabelDao.queryRaw(
				String.format(" where %s = ?", PropertyWithLabelDao.Properties.IsModified.columnName),
				String.valueOf(MODIFIEDTYPE.MODIFIED.ordinal()));
		for (PropertyLabelInfo propertyLabelInfo : propertyLabelInfos) {
			UnSubmitLabelInfo info = new UnSubmitLabelInfo();
			info.propertyLabelInfo = propertyLabelInfo;
			map.put(propertyLabelInfo.tag_code, info);
			List<PropertyGatherInfo> propertyGatherInfos = mPropertyDao.queryRaw(
					String.format(" where %s = ?", PropertyDao.Properties.Id.columnName),propertyLabelInfo.assert_id);
			info.name = propertyGatherInfos.get(0).name;
			info.code = propertyGatherInfos.get(0).code;
			list.add(info);
		}

		List<ScanData> scanDatas = mScanDatasDao.queryRaw(
				String.format(" where %s = ?", ScanDatasDao.Properties.IsModified.columnName),
				String.valueOf(MODIFIEDTYPE.MODIFIED.ordinal()));

		for (ScanData scanData : scanDatas) {
			if (map.containsKey(scanData.tag_code)) {
				if(scanData.scan_location_gps.equals("(4.9E-324,4.9E-324)")){
					scanData.scan_location_gps="";
				}
				map.get(scanData.tag_code).scanData = scanData;
			}
			
			
		}
		
		return list;
	}
	

	@Override
	public void clearAllTable() {
		mPropertyDao.deleteAll();
		mScanDatasDao.deleteAll();
		mPropertyWithLabelDao.deleteAll();
		mSupervisionDao.deleteAll();
		mTransportDatasDao.deleteAll();
	}
	

	@Override
	public void deleteLabel(String tagCode) {
		mPropertyWithLabelDao.delete(String.format(" where %s = '%s'",
				PropertyWithLabelDao.Properties.TagCode.columnName, tagCode));
		mScanDatasDao.delete(String.format(" where %s = '%s'",
				PropertyWithLabelDao.Properties.TagCode.columnName, tagCode));
	}

	@Override
	public boolean isExistLabel(String tagCode) {
		List<PropertyLabelInfo> list = mPropertyWithLabelDao.queryRaw(
				String.format(" where %s = ?", PropertyWithLabelDao.Properties.TagCode.columnName), tagCode);
		if (null != list && list.size() > 0) {
			return true;
		}
		return false;
	}

	@Override
	public void updateLabelPhotoFilePath(String tagCode, String photoPath, String breviaryPhotosPath) {
		mScanDatasDao.execSql(String.format("update %s set %s = '%s' ,%s = '%s' where %s = '%s'",
				ScanDatasDao.TABLENAME, ScanDatasDao.Properties.PhotosFilePath.columnName, photoPath,
				ScanDatasDao.Properties.BreviaryPhotosFilePath.columnName, breviaryPhotosPath,
				ScanDatasDao.Properties.TagCode.columnName, tagCode));
	}

	@Override
	public void resetLabelState(String tagCode) {
		mPropertyWithLabelDao.execSql(String.format("update %s set %s = '%s' where %s = '%s'",
				PropertyWithLabelDao.TABLENAME, PropertyWithLabelDao.Properties.IsModified.columnName,
				MODIFIEDTYPE.UNMODIFIED.ordinal(), PropertyWithLabelDao.Properties.TagCode.columnName,
				tagCode));
		mScanDatasDao.execSql(String.format("update %s set %s = '%s' where %s = '%s'",
				ScanDatasDao.TABLENAME, ScanDatasDao.Properties.IsModified.columnName,
				MODIFIEDTYPE.UNMODIFIED.ordinal(), ScanDatasDao.Properties.TagCode.columnName, tagCode));
	}

	@Override
	public void clearTags() {
		mTagsDao.deleteAll();
	}

	@Override
	public void insertTags(TagsInfo tagsInfo) {
		mTagsDao.insert(tagsInfo);
	}

	@Override
	public List<TagsInfo> getTagsInfos() {
		return mTagsDao.loadAll();
	}

	@Override
	public void updatePropertyInfo(PropertyGatherInfo info) {
		mPropertyDao.delete(String.format(" where %s = '%s'", PropertyDao.Properties.Id.columnName, info.id));
		mPropertyDao.insert(info);
	}

	@Override
	public void updatePropertyWithLabelDataInfo(PropertyLabelInfo info) {
		mPropertyWithLabelDao.delete(String.format(" where %s = '%s'",PropertyWithLabelDao.Properties.TagCode.columnName, info.tag_code));
		long insert = mPropertyWithLabelDao.insert(info);
//		System.out.println("插入第"+insert+"记录！！"+info.tag_code);
	}

	@Override
	public void updateScanData(ScanData info) {
		mScanDatasDao.delete(String.format(" where %s = '%s'", ScanDatasDao.Properties.Id.columnName,
				info.id));
		mScanDatasDao.insert(info);
	}

	@Override
	public void updateSupervision(SuperVisionInfo info) {
		mSupervisionDao.delete(String.format(" where %s = '%s'",
				SupervisionDao.Properties.AssertId.columnName, info.assert_id));
		mSupervisionDao.insert(info);
	}

	@Override
	public void updateTransportData(TransportDataInfo info) {
		mTransportDatasDao.delete(String.format(" where %s = '%s'",
				TransportDatasDao.Properties.AssertID.columnName, info.assert_id));
		mTransportDatasDao.insert(info);
	}

}
